package br.com.velp.sudecap.util;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;

/**
 * <sumario>
 * <objetivo>"Rastreabilidade"</objetivo>
 * <autor>EDUARDO SANTOS DE OLIVEIRA</autor>
 * <versao>1.0.0.0</versao>
 * <data_criacao> 05.06.2013 </data_criacao>
 * <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <requisito_afetado> N/A </requisito_afetado>
 * <descricao> Responsável Por Aplicar os Filtros de Consulta e Armazenar os Valores
 *             No Mapa de Parâmetros
 * </descricao>
 * </sumario>
 */
public class ConsultaFiltros {

    private StringBuilder filtros;
    private Map<String, Object> parametros;

    public ConsultaFiltros() {

        this.filtros = new StringBuilder();
        this.parametros = new HashMap<String, Object>();

    }

    public void addFiltroRegional(String campoSqlRegional, Long idRegional) {
        
        if (idRegional != null) {
            this.filtros.append("and ".concat(campoSqlRegional).concat(" = :idRegional "));
            this.parametros.put("idRegional", idRegional);
        }
        
    }

    public void addFiltroEmpreendimento(String campoSqlEmp, String empreendimento) {
        
        if (StringUtils.isNotBlank(empreendimento)) {
            this.filtros.append("and lower(".concat(campoSqlEmp).concat(") like '%' || lower(:empreendimento) || '%' "));
            this.parametros.put("empreendimento", empreendimento);
        }
        
    }

    public void addFiltroXplan(String campoSqlCodigoXplan, String sequencialXplan, String codigoXplan) {
        
        if (StringUtils.isNotBlank(sequencialXplan) && StringUtils.isBlank(codigoXplan)){
            this.filtros.append("and lower(".concat(campoSqlCodigoXplan).concat(") like lower(:sequencialXplan) || '%' "));
            this.parametros.put("sequencialXplan", sequencialXplan);
        } else if (StringUtils.isBlank(sequencialXplan) && StringUtils.isNotBlank(codigoXplan)){
            this.filtros.append("and lower(".concat(campoSqlCodigoXplan).concat(") like '%' || lower(:codigoXplan) "));
            this.parametros.put("codigoXplan", codigoXplan);
        } else if (StringUtils.isNotBlank(sequencialXplan) && StringUtils.isNotBlank(codigoXplan)){
            this.filtros.append("and lower(".concat(campoSqlCodigoXplan).concat(" = lower(:xplanCompleto) "));
            this.parametros.put("xplanCompleto", sequencialXplan.concat("-").concat(codigoXplan));
        }
        
    }
    
    public void addFiltroBairro(String campoSqlBairro, String campoBairroOficial, String bairro){
    
        if (StringUtils.isNotBlank(bairro)){
            this.filtros.append("and (lower(".concat(campoSqlBairro).concat(") like '%' || lower(:bairro) || '%' or lower(").concat(campoBairroOficial).concat(") like '%' || lower(:bairro) || '%') "));
            this.parametros.put("bairro", bairro);
        }
        
    }
    
    public void addFiltroCt(String campoSqlNumCt, String numeroCt){
        
        if (StringUtils.isNotBlank(numeroCt)){
            this.filtros.append("and lower(".concat(campoSqlNumCt).concat(") like :numeroCt || '%' "));
            this.parametros.put("numeroCt", numeroCt);
        }
        
    }
    
    public void addFiltroCtmSetor(String campoSqlCtmSetor, String ctmSetor){
        
        if (StringUtils.isNotBlank(ctmSetor)){
            if (ctmSetor.matches("^[0-9]*$")){
                this.filtros.append("and regexp_like(".concat(campoSqlCtmSetor).concat(", '^-?[[:digit:],.]*$') and to_number(regexp_replace(").concat(campoSqlCtmSetor).concat(", '[^0-9]', '')) = to_number(:ctmSetor) "));
            } else {
                this.filtros.append("and lower(".concat(campoSqlCtmSetor).concat(") like '%' || lower(:ctmSetor) || '%' "));
            }
            this.parametros.put("ctmSetor", ctmSetor);
        }
        
    }
    
    public void addFiltroCtmQuadra(String campoSqlCtmQuadra, String ctmQuadra){
        
        if (StringUtils.isNotBlank(ctmQuadra)){
            if (ctmQuadra.matches("^[0-9]*$")){
                this.filtros.append("and regexp_like(".concat(campoSqlCtmQuadra).concat(", '^-?[[:digit:],.]*$') and to_number(regexp_replace(").concat(campoSqlCtmQuadra).concat(", '[^0-9]', '')) = to_number(:ctmQuadra) "));
            } else {
                this.filtros.append("and lower(".concat(campoSqlCtmQuadra).concat(") like '%' || lower(:ctmQuadra) || '%' "));
            }
            this.parametros.put("ctmQuadra", ctmQuadra);
        }
        
    }
    
    public void addFiltroCtmImovel(String campoSqlCtmImovel, String ctmImovel){
        
        if (StringUtils.isNotBlank(ctmImovel)){
            if (ctmImovel.matches("^[0-9]*$")){
                this.filtros.append("and regexp_like(".concat(campoSqlCtmImovel).concat(", '^-?[[:digit:],.]*$') and to_number(regexp_replace(").concat(campoSqlCtmImovel).concat(", '[^0-9]', '')) = to_number(:ctmImovel) "));
            } else {
                this.filtros.append("and lower(".concat(campoSqlCtmImovel).concat(") like '%' || lower(:ctmImovel) || '%' "));
            }
            this.parametros.put("ctmImovel", ctmImovel);
        }
        
    }
    
    public void addFiltroQuadra(String campoSqlQuadra, String quadra){
        
        if (StringUtils.isNotBlank(quadra)){
            if (quadra.matches("^[0-9]*$")){
                this.filtros.append("and regexp_like(".concat(campoSqlQuadra).concat(", '^-?[[:digit:],.]*$') and to_number(regexp_replace(").concat(campoSqlQuadra).concat(", '[^0-9]', '')) = to_number(:quadra) "));
            } else {
                this.filtros.append("and lower(".concat(campoSqlQuadra).concat(") like '%' || lower(:quadra) || '%' "));
            }
            this.parametros.put("quadra", quadra);
        }
        
    }
    
    public void addFiltroLote(String campoSqlLote, String lote){
        
        if (StringUtils.isNotBlank(lote)){
            if (lote.matches("^[0-9]*$")){
                this.filtros.append("and regexp_like(".concat(campoSqlLote).concat(", '^-?[[:digit:],.]*$') and to_number(regexp_replace(").concat(campoSqlLote).concat(", '[^0-9]', '')) = to_number(:lote) "));
            } else {
                this.filtros.append("and lower(".concat(campoSqlLote).concat(") like '%' || lower(:lote) || '%' "));
            }
            this.parametros.put("lote", lote);
        }
        
    }
    
    public void addFiltroLogradouro(String campoSqlLogradouro, String logradouro){
        
        if (StringUtils.isNotBlank(logradouro)){
            this.filtros.append("and lower(".concat(campoSqlLogradouro).concat(") like '%' || lower(:logradouro) || '%' "));
            this.parametros.put("logradouro", logradouro);
        }
        
    }
    
    public void addFiltroNumProcessoAdm(String campoSqlProcessoAdm, String numProcessoAdm){
        
        if (StringUtils.isNotBlank(numProcessoAdm)){
            this.filtros.append("and lower(".concat(campoSqlProcessoAdm).concat(") = lower(:numProcessoAdm) "));
            this.parametros.put("numProcessoAdm", numProcessoAdm);
        }
        
    }
    
    public void addFiltroNumProcessoJud(String campoSqlIdImovelEmp, String numProcessoJudicial){
        
        if (StringUtils.isNotBlank(numProcessoJudicial)){
            this.filtros.append("and ".concat(campoSqlIdImovelEmp).concat(" in "));
            this.filtros.append("(select jie.id_imovel_emp ");
            this.filtros.append(" from processo_juridico pjud ");
            this.filtros.append(" inner join juridico_imovel_emp jie on (pjud.id_process_jur = jie.id_process_jur) ");
            this.filtros.append(" where lower(pjud.num_process_jud) = lower(:numProcessoJudicial) ");
            this.filtros.append(" and jie.id_imovel_emp = ").append(campoSqlIdImovelEmp).append(") ");
            this.parametros.put("numProcessoJudicial", numProcessoJudicial);
        }
        
    }
    
    public void addFiltroPessoaImovel(String campoSqlIdImovel, String nomePessoa){
        
        if (StringUtils.isNotBlank(nomePessoa)){
            this.filtros.append("and to_char(".concat(campoSqlIdImovel).concat(") in (func_get_ids_pess_imo(".concat(campoSqlIdImovel).concat(", :pessoa)) ")));
            this.parametros.put("pessoa", nomePessoa);
        }
        
    }
    
    public void addFiltroPessoaProcessoAdministrativo(String campoSqlIdImovel, String nomePessoa){
        
        if (StringUtils.isNotBlank(nomePessoa)){
            this.filtros.append("and to_char(".concat(campoSqlIdImovel).concat(") in (func_get_ids_prop_proc_adm(".concat(campoSqlIdImovel).concat(", :pessoa)) ")));
            this.parametros.put("pessoa", nomePessoa);
        }
        
    }
    
    public void addFiltroNumeroDecreto(String campoSqlIdImovel, String numeroDecreto){
        
        if (StringUtils.isNotBlank(numeroDecreto)){
            this.filtros.append("and to_char(".concat(campoSqlIdImovel).concat(") in (func_get_ids_decreto_imo(").concat(campoSqlIdImovel).concat(", :numeroDecreto)) "));
            this.parametros.put("numeroDecreto", numeroDecreto);
        }
        
    }
    
    public void addFiltroNumLaudoAval(String campoSqlNumLaudoAval, String numLaudoAval){
        
        if (StringUtils.isNotBlank(numLaudoAval)){
            this.filtros.append("and ").append(campoSqlNumLaudoAval).append(" = :numeroLaudo ");
            this.parametros.put("numeroLaudo", numLaudoAval);
        }
        
    }
    
    public void addFiltroAnoLaudoAval(String campoSqlAnoLaudoAval, Integer anoLaudoAval){
        
        if (anoLaudoAval != null){
            this.filtros.append("and ").append(campoSqlAnoLaudoAval).append(" = :anoLaudo ");
            this.parametros.put("anoLaudo", anoLaudoAval);
        }
        
    }
    
    public void addFiltroDataLaudoAval(String campoSqlDataLaudoAval, Date dataLaudoAval){
        
        if (dataLaudoAval != null){
            this.filtros.append("and ").append(campoSqlDataLaudoAval).append(" = :dataLaudo ");
            this.parametros.put("dataLaudo", dataLaudoAval);
        }
        
    }
    
    public void addFiltroSituacaoProcessoAdm(String campoSqlSituacaoProcAdm, String situacaoProcessoAdm){
        
        if (StringUtils.isNotBlank(situacaoProcessoAdm)){
            this.filtros.append("and ").append(campoSqlSituacaoProcAdm).append(" = :situacao ");
            this.parametros.put("situacao", situacaoProcessoAdm);
        }
        
    }
    
    public void addFiltroZona(String campoSqlZona, String zona){
        
        if (StringUtils.isNotBlank(zona)){
            this.filtros.append("and lower(").append(campoSqlZona).append(") like '%' || lower(:zona) || '%' ");
            this.parametros.put("zona", zona);
        }
        
    }
    
    public void addFiltroIdRegistro(String campoSqlId, Long idRegistro) {
        
        if (idRegistro != null) {
            this.filtros.append("and ").append(campoSqlId).append(" = :id ");
            this.parametros.put("id", idRegistro);
        }
        
    }
    
    public void addFiltroSqlEqual(String campoSql, String alias, Object valorFiltro) {
        
        if (valorFiltro != null && !"".equals(valorFiltro)){
            this.filtros.append("and lower(").append(campoSql).append(") = lower(:").append(alias).append(") ");
            this.parametros.put(alias, valorFiltro);
        }
        
    }
    
    public void addFiltroSqlNotEqual(String campoSql, String alias, Object valorFiltro) {
        
        if (valorFiltro != null && !"".equals(valorFiltro)){
            this.filtros.append("and ").append(campoSql).append(" <> :").append(alias).append(" ");
            this.parametros.put(alias, valorFiltro);
        }
        
    }
    
    public void addFiltroSqlLikeAnyWhere(String campoSql, String alias, String valorFiltro) {
        
        if (StringUtils.isNotBlank(valorFiltro)){
            this.filtros.append("and lower(").append(campoSql).append(") like '%' || lower(:").append(alias).append(") || '%' ");
            this.parametros.put(alias, valorFiltro);
        }
        
    }
    
    public void addFiltroSqlLikeStart(String campoSql, String alias, String valorFiltro) {
        
        if (StringUtils.isNotBlank(valorFiltro)){
            this.filtros.append("and lower(").append(campoSql).append(") like lower(:").append(alias).append(") || '%' ");
            this.parametros.put(alias, valorFiltro);
        }
        
    }
    
    public void addFiltroSqlLikeEnd(String campoSql, String alias, String valorFiltro) {
        
        if (StringUtils.isNotBlank(valorFiltro)){
            this.filtros.append("and lower(").append(campoSql).append(") like '%' || lower(:").append(alias).append(") ");
            this.parametros.put(alias, valorFiltro);
        }
        
    }
    
    public void addFiltroSqlIn(String campoSqlId, String subQuery) {
        
        if (StringUtils.isNotBlank(subQuery)) {
            this.filtros.append("and ").append(campoSqlId).append(" in (").append(subQuery).append(") ");
        }
        
    }
    
    public void addFiltroSqlNotIn(String campoSqlId, String subQuery) {
        
        if (StringUtils.isNotBlank(subQuery)) {
            this.filtros.append("and ").append(campoSqlId).append(" not in (").append(subQuery).append(") ");
        }
        
    }
    
    public void addFiltroSqlGe(String campoSqlId, String alias, Date dataParam) {
        
        if (dataParam != null) {
            this.filtros.append("and ").append(campoSqlId).append(" >= :").append(alias).append(" ");
            this.parametros.put(alias, dataParam);
        }
        
    }
    
    public void addFiltroSqlLe(String campoSqlId, String alias, Date dataParam) {
        
        if (dataParam != null) {
            this.filtros.append("and ").append(campoSqlId).append(" <= :").append(alias).append(" ");
            this.parametros.put(alias, dataParam);
        }
        
    }
    
    public void addFiltroSqlIsNotNull(String campoSqlId) {
        
        this.filtros.append("and ").append(campoSqlId).append(" is not null ");
        
    }
    
    public StringBuilder getFiltros() {
        return this.filtros;
    }

    public Map<String, Object> getParametros() {
        return this.parametros;
    }
    
}
